home *** CD-ROM | disk | FTP | other *** search
/ Aminet 24 / Aminet 24 (1998)(GTI - Schatztruhe)[!][Apr 1998].iso / Aminet / dev / c / AmiVoGL_MDEV.lha / src / objects.c < prev    next >
C/C++ Source or Header  |  1994-04-12  |  9KB  |  495 lines

  1. /* objects.c: */
  2. #include <stdio.h>
  3. #include "vogl.h"
  4.  
  5. /* ---------------------------------------------------------------------
  6.  * Typedefs and Variables:
  7.  */
  8. typedef struct o{
  9.     int        obno;
  10.     TokList        *tlist;
  11.     struct o    *next;
  12.     } VObject;
  13.  
  14. static VObject        *object_table[MAXENTS];
  15.  
  16. static long        obno = -1, omax = 0;
  17.  
  18. /* ---------------------------------------------------------------------
  19.  * Prototypes:
  20.  */
  21. #ifdef __PROTOTYPE__
  22. static void doarc( float, float, float, float, float,  /* objects.c       */
  23.    float, int);
  24. static void doarcf( float, float, float, float, float, /* objects.c       */
  25.    float, int);
  26. #else
  27. static void doarc();                                   /* objects.c       */
  28. static void doarcf();                                  /* objects.c       */
  29. #endif
  30.  
  31. /* ---------------------------------------------------------------------
  32.  * Source Code:
  33.  */
  34.  
  35. /*
  36.  * makeobj
  37.  *
  38.  *    start a new object.
  39.  *
  40.  */
  41. void makeobj(long ob)
  42. {
  43. VObject    *o;
  44. int    n = ob;
  45.  
  46. if (!vdevice.initialised)
  47. verror("makeobj: vogl not initialised");
  48.  
  49. for (o = object_table[n % MAXENTS]; o != (VObject *)NULL; o = o->next)
  50. if (o->obno == n) {
  51.     delobj((long)n);
  52.     break;
  53.     }
  54.  
  55. obno = n;
  56. vdevice.tokens = (TokList *)NULL;
  57.  
  58. vdevice.inobject = 1;
  59.  
  60. if (omax <= n)
  61. omax = n + 1;
  62. }
  63.  
  64. /* ------------------------------------------------------------------------ */
  65.  
  66. /*
  67.  * closeobj
  68.  *
  69.  *    close an object
  70.  */
  71. void closeobj(void)
  72. {
  73. VObject    *o;
  74.  
  75. if (!vdevice.inobject)
  76. verror("closeobj: not in an object");
  77.  
  78. vdevice.inobject = 0;
  79.  
  80. o = (VObject *)vallocate(sizeof(VObject));
  81. o->obno = obno;
  82. o->tlist = vdevice.tokens;
  83. o->next = object_table[obno % MAXENTS];
  84.  
  85. object_table[obno % MAXENTS] = o;
  86.  
  87. obno = -1;
  88. }
  89.  
  90. /* ------------------------------------------------------------------------ */
  91.  
  92. /*
  93.  * delobj
  94.  *
  95.  *    deletes an object, freeing its memory
  96.  */
  97. void delobj(long ob)
  98. {
  99. VObject    *o, *lo;
  100. TokList    *tl, *ntl;
  101. int    n = ob;
  102.  
  103. for (lo = o = object_table[n % MAXENTS]; o != (VObject *)NULL; lo = o, o = o->next)
  104. if (o->obno == n)
  105. break;
  106.  
  107. if (o != (VObject *)NULL) {
  108.     for (tl = o->tlist; tl != (TokList *)NULL; tl = ntl) {
  109.         ntl = tl->next;
  110.         if (tl->toks)
  111.         free(tl->toks);
  112.  
  113.         free(tl);
  114.         }
  115.     if (lo == object_table[n % MAXENTS])
  116.     object_table[n % MAXENTS] = (VObject *)NULL;
  117.     else
  118.     lo->next = o->next;
  119.     free(o);
  120.     }
  121. }
  122.  
  123. /* ------------------------------------------------------------------------ */
  124.  
  125. /*
  126.  * genobj
  127.  *
  128.  *    generates a unique object identifier
  129.  */
  130. long genobj(void)
  131. {
  132. return((long)omax++);
  133. }
  134.  
  135. /* ------------------------------------------------------------------------ */
  136.  
  137. /*
  138.  * getopenobj
  139.  *
  140.  *    returns the object currently being edited, -1 if none.
  141.  */
  142. long getopenobj(void)
  143. {
  144. return((long)obno);
  145. }
  146.  
  147. /* ------------------------------------------------------------------------ */
  148.  
  149. /*
  150.  * doarc
  151.  *
  152.  *    draw an arc or circle.
  153.  */
  154. static void doarc(
  155.   float x,
  156.   float y,
  157.   float xoff,
  158.   float yoff,
  159.   float cosine,
  160.   float sine,
  161.   int nsegs)
  162. {
  163. float    cx, cy, dx, dy;
  164. int    i;
  165.  
  166. cx = x + xoff;
  167. cy = y + yoff;
  168. move2(cx, cy);
  169.  
  170. for (i = 0; i < nsegs; i++) {
  171.     dx = cx - x;
  172.     dy = cy - y;
  173.     cx = x + dx * cosine - dy * sine;
  174.     cy = y + dx * sine + dy * cosine;
  175.     draw2(cx, cy);
  176.     }
  177. }
  178.  
  179. /* ------------------------------------------------------------------------ */
  180.  
  181. /*
  182.  * doarcf
  183.  *
  184.  *    draw a filled arc or circle.
  185.  */
  186. static void doarcf(
  187.   float x,
  188.   float y,
  189.   float xoff,
  190.   float yoff,
  191.   float cosine,
  192.   float sine,
  193.   int nsegs)
  194. {
  195. float    cx, cy, dx, dy;
  196. int    i;
  197.  
  198. cx = x + xoff;
  199. cy = y + yoff;
  200. pmv2(cx, cy);
  201.  
  202. for (i = 0; i < nsegs; i++) {
  203.     dx = cx - x;
  204.     dy = cy - y;
  205.     cx = x + dx * cosine - dy * sine;
  206.     cy = y + dx * sine + dy * cosine;
  207.     pdr2(cx, cy);
  208.     }
  209.  
  210. pclos();
  211. }
  212.  
  213. /* ------------------------------------------------------------------------ */
  214.  
  215. /*
  216.  * callobj
  217.  *
  218.  *    draws an object
  219.  */
  220. void callobj(long ob)
  221. {
  222. int    n = ob;
  223. char    buf[BUFSIZ];
  224.  
  225. VObject        *o;
  226. TokList        *tl;
  227. Matrix          prod, tmpmat;
  228. Tensor          S;
  229. int             i, j;
  230. float           cx, cy, cz, *m;
  231. register Token *t, *et, *pt;
  232.  
  233. if (!vdevice.initialised)
  234. verror("callobj: vogl not initialised");
  235.  
  236. if (vdevice.inobject) {
  237.     t = newtokens(2);
  238.  
  239.     t[0].i = CALLOBJ;
  240.     t[1].i = n;
  241.  
  242.     return;
  243.     }
  244.  
  245. for (o = object_table[n % MAXENTS]; o != (VObject *)NULL; o = o->next)
  246. if (o->obno == n)
  247. break;
  248.  
  249. if (o == (VObject *)NULL)
  250. return;
  251.  
  252. for (tl = o->tlist; tl != (TokList *)NULL; tl = tl->next) {
  253.     t = tl->toks;
  254.     et = &tl->toks[tl->count];
  255.     while (t != et) {
  256.         switch (t->i) {
  257.         case ARC:
  258.             doarc(t[1].f, t[2].f, t[3].f, t[4].f, t[5].f, t[6].f, t[7].i);
  259.             t += 8;
  260.             break;
  261.         case ARCF:
  262.             doarcf(t[1].f, t[2].f, t[3].f, t[4].f, t[5].f, t[6].f, t[7].i);
  263.             t += 8;
  264.             break;
  265.         case BACKBUFFER:
  266.             backbuffer(t[1].i);
  267.             t += 2;
  268.             break;
  269.         case FRONTBUFFER:
  270.             frontbuffer(t[1].i);
  271.             t += 2;
  272.             break;
  273.         case SWAPBUFFERS:
  274.             swapbuffers();
  275.             t += 1;
  276.             break;
  277.         case BACKFACING:
  278.             backface(t[1].i);
  279.             t += 2;
  280.             break;
  281.         case CALLOBJ:
  282.             callobj(t[1].i);
  283.             t += 2;
  284.             break;
  285.         case CIRCLE:
  286.             doarc(t[1].f, t[2].f, t[3].f, 0.0, t[4].f, t[5].f, t[6].i);
  287.             draw2(t[1].f + t[3].f, t[2].f);
  288.             t += 7;
  289.             break;
  290.         case CIRCF:
  291.             doarcf(t[1].f, t[2].f, t[3].f, 0.0, t[4].f, t[5].f, t[6].i);
  292.             t += 7;
  293.             break;
  294.         case RECTF:
  295.             pmv2(t[1].f, t[2].f);
  296.             pdr2(t[3].f, t[2].f);
  297.             pdr2(t[3].f, t[4].f);
  298.             pdr2(t[1].f, t[4].f);
  299.             pdr2(t[1].f, t[2].f);
  300.             pclos();
  301.             t += 5;
  302.             break;
  303.         case CLEAR:
  304.             (*vdevice.dev.Vclear)();
  305.             t++;
  306.             break;
  307.         case COLOR:
  308.             color(t[1].i);
  309.             t += 2;
  310.             break;
  311.         case DRAW:
  312.             draw(t[1].f, t[2].f, t[3].f);
  313.             t += 4;
  314.             break;
  315.         case DRAWSTR:
  316.             charstr((char *) &t[1]);
  317.             t += 2 + strlen((char *) &t[1]) / sizeof(Token);
  318.             break;
  319.         case FONT:
  320.             font((short) t[1].i);
  321.             t += 2;
  322.             break;
  323.         case LOADMATRIX:
  324.             m = (float *)vdevice.transmat->m;
  325.             for (i = 0; i < 16; i++)
  326.             *m++ = (++t)->f;
  327.  
  328.             /* may have changed mapping from world to device coords */
  329.             vdevice.cpVvalid = 0;
  330.             t++;
  331.  
  332.             break;
  333.         case MAPCOLOR:
  334.             mapcolor((Colorindex) t[1].i,
  335.               (short) t[2].i,
  336.               (short) t[3].i,
  337.               (short) t[4].i);
  338.             t += 5;
  339.             break;
  340.         case MOVE:
  341.             move(t[1].f, t[2].f, t[3].f);
  342.             t += 4;
  343.             break;
  344.         case MULTMATRIX:
  345.             m = (float *)tmpmat;
  346.             for (i = 0; i < 16; i++)
  347.             *m++ = (++t)->f;
  348.  
  349.             mult4x4(prod, tmpmat, vdevice.transmat->m);
  350.             loadmatrix(prod);
  351.             t++;
  352.             break;
  353.         case POLY:
  354.             polyobj(t[1].i, &t[2], 0);
  355.             t += 2 + 3 * t[1].i;
  356.             break;
  357.         case POLYF:
  358.             polyobj(t[1].i, &t[2], 1);
  359.             t += 2 + 3 * t[1].i;
  360.             break;
  361.         case CMOV:
  362.             cmov(t[1].f, t[2].f, t[3].f);
  363.             t += 4;
  364.             break;
  365.         case POPATTRIBUTES:
  366.             popattributes();
  367.             t++;
  368.             break;
  369.         case POPMATRIX:
  370.             popmatrix();
  371.             t++;
  372.             break;
  373.         case POPVIEWPORT:
  374.             popviewport();
  375.             t++;
  376.             break;
  377.         case PUSHATTRIBUTES:
  378.             pushattributes();
  379.             t++;
  380.             break;
  381.         case PUSHMATRIX:
  382.             pushmatrix();
  383.             t++;
  384.             break;
  385.         case PUSHVIEWPORT:
  386.             pushviewport();
  387.             t++;
  388.             break;
  389.         case RCURVE:
  390.             i = (++t)->i;
  391.             cx = (++t)->f;
  392.             cy = (++t)->f;
  393.             cz = (++t)->f;
  394.             m = (float *)tmpmat;
  395.             for (j = 0; j < 16; j++)
  396.             *m++ = (++t)->f;
  397.             mult4x4(prod, tmpmat, vdevice.transmat->m);
  398.             drcurve(i, prod);
  399.             vdevice.cpW[V_X] = cx;
  400.             vdevice.cpW[V_Y] = cy;
  401.             vdevice.cpW[V_Z] = cz;
  402.             t++;
  403.             break;
  404.         case RPATCH:
  405.             pt = t + 10;
  406.             cx = (++t)->f;
  407.             cy = (++t)->f;
  408.             cz = (++t)->f;
  409.             for (i = 0; i < 4; i++)
  410.             for (j = 0; j < 4; j++) {
  411.                 S[0][i][j] = (pt++)->f;
  412.                 S[1][i][j] = (pt++)->f;
  413.                 S[2][i][j] = (pt++)->f;
  414.                 S[3][i][j] = (pt++)->f;
  415.                 }
  416.  
  417.             transformtensor(S, vdevice.transmat->m);
  418.             drpatch(S, t[1].i, t[2].i, t[3].i, t[4].i, t[5].i, t[6].i);
  419.  
  420.             vdevice.cpW[V_X] = cx;
  421.             vdevice.cpW[V_Y] = cy;
  422.             vdevice.cpW[V_Z] = cz;
  423.             t = pt;
  424.             break;
  425.         case VIEWPORT:
  426.             viewport(
  427.               (Screencoord) t[1].i,
  428.               (Screencoord) t[2].i,
  429.               (Screencoord) t[3].i,
  430.               (Screencoord) t[4].i);
  431.             t += 5;
  432.             break;
  433.         case TRANSLATE:
  434.             translate(t[1].f, t[2].f, t[3].f);
  435.             t += 4;
  436.             break;
  437.         case SCALE:
  438.             /*
  439.              * Do the operations directly on the top matrix of
  440.              * the stack to speed things up.
  441.              */
  442.  
  443.             vdevice.transmat->m[0][0] *= t[1].f;
  444.             vdevice.transmat->m[0][1] *= t[1].f;
  445.             vdevice.transmat->m[0][2] *= t[1].f;
  446.             vdevice.transmat->m[0][3] *= t[1].f;
  447.  
  448.             vdevice.transmat->m[1][0] *= t[2].f;
  449.             vdevice.transmat->m[1][1] *= t[2].f;
  450.